home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
print
/
lp_oki.zip
/
LP14.ASM
< prev
next >
Wrap
Assembly Source File
|
1985-08-08
|
14KB
|
675 lines
Title LP - Print File With Pagination
Page 80,132
Comment |
LP Command
________________
Purpose: To print an ASCII file on the standard printer
device at either 66 or 88 lines per page. A title
is printed at the top of each page which contains
the file name, creation date, and page number.
Syntax: LP [d][path]filename[.ext] [/6][/8]
[/L1][/L2]
[/10][/12][/17]
Remarks:
Written by Vernon Buerg for the IBM PC using
DOS 2.0 or later. For public domain use. Not
for sale or hire.
Version 1.1, April 27, 1984.
Version 1.2, Sept 12, 1984.
Version 1.4, Aug 8, 1985.
- account for TABs and long lines
- remove Int 17h due to bad spoolers
________________ |
Cseg Segment Public Para 'CODE'
Assume CS:Cseg,DS:Cseg
Org 100h
LP Proc Far
Mov SP,Offset CS:Lstack ;Use local stack
Push DS ;For DOS return
Sub AX,AX
Push AX
Mov Stk_Top,SP
Call Ver ; Check DOS version
Call Alloc ; Allocate memory
Call GetFile ; Get file name
Call Opens ; Open input
Call InitLPT ; Initialize printer
Call GetName ; Format title line
Call Titles ; and print it
Call List ; Print the file
Call Flush ; Drain the output buffer
Eod: Mov DX,Offset EofMsg ;Say END-OF-FILE
Jmp Fini
Error: Mov CS:Errlvl,1
Fini: Mov AX,CS ;Insure seg regs
Mov DS,AX
Mov SP,Stk_Top ; and stackck
Mov AH,9 ;Print error message
Int 21h
Mov BX,IHandle ;Close input
Mov AH,3Eh
Int 21h
Mov BX,OHandle ; Close output
Cmp BX,4 ; if not standard output
Je Exit
Mov AH,3Eh
Int 21h
Exit:
Mov AL,Errlvl ; Set ERROR LEVEL
Mov AH,4Ch ; and Exit
Int 21h
Page
;
; Constants and Data Areas
BEL Equ 07
BS Equ 08
TAB Equ 09
LF Equ 10
FF Equ 12
CR Equ 13
EOF Equ 1Ah
ESC Equ 1Bh
Buflen Dw 0 ;I/O buffer size (variable)
Stk_Top Dw 0 ;Stack ptr at entry
Lcnt Db 0 ;Line counter
Cpp Db 96 ;Chars per page
LPP Db 82 ;Lines per page
LPTn Dw 0 ;Printer port
Errlvl Db 0 ;Error level returned
Ccnt Db 0 ;Chars in current line
MsgIn Db CR,LF,'Enter INPUT filename $'
Msg1 Db CR,LF,'Unable to open input'
InKey Db 32,32 ;Keyboard buffer
Input Db 76 Dup (0),'$' ;Drive:path\name.ext
IHandle Dw 0 ;Input file handle
Ilen Dw 0 ;Input block length
Iptr Dw 0 ;Offset to next char
InPtr Dw 0 ;Offset to input buffer
Msg2 Db CR,LF,'Unable to open LPT'
Msg2a Db '1$'
Output Db 'LPT1:',0,'$' ;Printer name
OHandle Dw 0 ;Output file handle
Olen Dw 0 ;Output block length
Optr Dw 0 ;Offset to next char
OutPtr Dw 0 ;Offset to output buffer
OutChar Db 0
AlocMsg Db CR,LF,'Not enough memory',CR,LF,BEL,'$'
ErrMsg Db CR,LF,'Invalid command option(s)',CR,LF,BEL,'$'
Version Db 'LP - Version 1.4 - V.Buerg',CR,LF,'$'
Sorry Db 'Sorry, PC DOS 2.0 or later required',CR,LF,BEL,'$'
Heading Db CR ;Top line title
FileNm Db 43 Dup (' ')
Date Db 'mm-dd-yy',9,9
Db 'Page '
Pageno Db '1',LF
EofMsg Db CR,LF
Len_H Equ This Byte - Heading
Db 'End of File',CR,LF,'$'
Dater Record Yr:7,Mo:4,Dy:5
Reset Db CR ;Printer initialization codes
Db FF,ESC ;Form feed (no CPI setting)
Lpi Db 56 ;Lines per inch
Cpi Db 28 ;Chars per inch
Tabs Db ESC,TAB
Db '009,017,025,033,041,049,057,065,073'
Reset10 Equ $-Reset+1
Tabs12 Db ',081,089' ; When using 12-cpi
Reset12 Equ $-Reset+1
Tabs17 Db ',097,105,113,121,129',CR
Reset17 Equ $-Reset
Reset_L Dw Reset12 ; Length of initial string
Page
;
; Copy file to printer
List Proc Near
List1: Call Read ;Get one character
And AL,7FH ;Strip hi-order bit
Cmp AL,FF ;Is it form feed?
Je Eject
Cmp AL,LF ;Pass line feed
Je Passit
Cmp AL,CR ;Pass carriage return
Je Passit
Cmp AL,BS ;Pass back space
Je PassBS
Cmp AL,TAB ;Pass tab chars
Je PassTAB
Inc Ccnt ;Incr count of chars in line
Cmp AL,EOF ;End of file?
Je Done
Cmp AL,32 ;Other control char?
Jns Passit
Jmp CtlChr
PassTAB:Add Ccnt,8 ;Round up to TAB column
And Ccnt,0F8h
Jmp Passit
PassBS: Dec Ccnt ;Account for backspace
Jns Passit
Mov Ccnt,0
Passit: Call PutChar
Mov AH,Cpp ;Max chars per line
Cmp Ccnt,AH ; filled up a line?
Ja Passit2
Passit1:
Cmp AL,LF ;Is it line feed?
Jne List1 ; no, get next char
Passit2:
Inc Lcnt ; yes, incr line count
Mov Ccnt,0
Mov AL,Lcnt
Cmp AL,LPP ;End of page?
Jb List1 ; no, get next char
Eject: Mov Ccnt,0 ;Reset char count in line
Cmp Lcnt,2 ;Printed any lines yet?
Jbe List1 ; no, ignore form feed
Call NewPage
Jmp List1 ;Get next record
CtlChr: Cmp AL,0 ;Null char?
Je Blanks ; yes, make it a space
Push AX
Mov AL,'^' ;Indicate a control char
Call PutChar
Inc Ccnt
Pop AX ;Get char again
Blanks: Add AL,20H ;Make it printable
Jmp Passit
Done: Ret
List Endp
Page
;
; Process end of page
NewPage Proc Near
Cmp Lcnt,2 ;Is it title line?
Je Titles ; yes, skip rest
Mov AL,CR
Call PutChar ; no, send CR
Mov AL,FF
Call PutChar ; and form feed
Mov Lcnt,0 ;Reset line count
Push DI
Mov DI,Offset Pageno
Mov AX,3A30h
Next: Inc Byte Ptr [DI] ;Incr page number
Cmp [DI],AL ;End in zero?
Js Set1 ; yes, make it a one
Cmp [DI],AH ;Over nine?
Jne PgSet ; no, have good number
Mov [DI],AL ; yes, make last digit zero
Dec DI ; and incr hi-order
Jmp Next
Set1: Mov Byte Ptr [DI],'1'
PgSet: Pop DI
;
; Print top line titles
Titles: Mov SI,Offset Heading ;Print title line
Mov CX,Len_H
Next1: Lodsb
Cmp AL,0 ;Replace nulls
Jne Next2
Mov AL,' '
Next2: Call PutChar
Loop Next1
Mov Lcnt,2 ;Reset line counter
Ret
;
; Initialize the printer
InitLPT Proc Near ;Initialize the printer
Init1: Mov CX,Reset_L ;Length of
Mov SI,Offset Reset ; initial codes
Init2: Call Next1
Ret
InitLPT Endp
NewPage Endp
Page
;
; Format title line
GetName Proc Near ;Format title line
Mov SI,Offset Input ;Copy file name
Mov DI,Offset Filenm ; to heading
Mov CX,42 ;Max for title
Cld
Repz Movsb
Mov AX,5700h ;Return file's date and time
Mov BX,IHandle ;Input handle
Int 21h
Mov DI,Offset Date ;Date field in title
Mov AX,DX ;Get month part
And AX,Mask Mo
Mov CL,Mo
Call Format
Stosw
Inc DI ;Add delimiter
Mov AX,DX ;Get day part
And AX,Mask Dy
Mov CL,Dy
Call Format
Stosw
Inc DI ;Add delimiter
Mov AX,DX ;Get year part
And AX,Mask Yr
Mov CL,Yr
Call Format
Or AL,'8'
Stosw
Ret
GetName Endp
Format Proc Near ;Convert binary to ASCII
Shr AX,CL
Aam
Or AX,'00'
Xchg AH,AL
Ret
Format Endp
Page
;
; Extract one char from record
Read Proc Near ;Read char into AL
Read1: Cmp Ilen,0 ;Any in buffer?
Je Read2 ; no, read next block
Mov SI,Iptr ; yes, get offset in buf
Lodsb
Inc Iptr ;Offset for next one
Dec Ilen ;Decr buffer size left
Ret ; and return
Read2: Mov BX,IHandle ;Read input
Mov CX,BufLen
Mov DX,InPtr ;Set up DS:DX
Mov AH,3Fh
Int 21h ;Read a block
Mov DX,InPtr
Mov Iptr,DX ;Reset buffer ptr
Mov Ilen,AX ; and length
Jc Read8
Or AX,AX ;Anything read?
Jnz Read1 ; yes, pick it up
Mov AL,EOF ; no, return EOF
Ret
Read8: Mov DX,Offset Msg3 ;Say I/O ERROR
Jmp Error
Msg3 Db CR,LF,'I/O error',CR,LF,BEL,'$'
Read Endp
;
; Buffer characters to printer
PutChar Proc Near ;Write from AL
Mov DI,Optr ; Spot for next outchar
Stosb
Mov Optr,DI
Dec Olen ; Is it full now?
Jz PutCh0 ; yes, print the lot
Ret
Flush: Mov AX,Olen ; Bytes left in output buffer
Sub Buflen,AX ; to get count in buffer
Jnz PutCh0
Ret
PutCh0: Push AX
Push BX
Push CX
Push DX
PutCh1: Mov BX,OHandle ; Printer file handle
Mov CX,Buflen
Mov Olen,CX ; Reset size remaining in bufr
Mov DX,OutPtr
Mov Optr,DX ; Reset ptr for next put
Mov AH,40h ; Print entire buffer
Int 21h
Jc PutChe ; Successful?
Cmp AX,CX ; Wrote it all?
Je PutCh9
PutChe: Mov DX,Offset MsgPut ; Printer error
Or MsgPute,AL
Jmp Error
Msg